﻿
// WxBootDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "WxBoot.h"
#include "WxBootDlg.h"
#include "db.h"
#include "socket.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//dll的进程id
DWORD DLL_PROCCESS_ID;

//定时器执行步长
UINT TIMER_STEP = 3600000;

//定时器ID
UINT TIMER_ID = 666;

//当前执行路径
CString CurrentExePath;

//ClistCtr控件
CListCtrl* List;

// CWxBootDlg 对话框

CWxBootDlg::CWxBootDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_WXBOOT_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWxBootDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO_TYPE, CCombo);
}

BEGIN_MESSAGE_MAP(CWxBootDlg, CDialogEx)
//	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
//	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_COPYDATA()
//	ON_NOTIFY(NM_RCLICK, IDC_CONTACT, &CWxBootDlg::OnNMRClickContact)
	ON_CBN_SELCHANGE(IDC_COMBO_TYPE, &CWxBootDlg::OnCbnSelchangeComboType)
	ON_NOTIFY(NM_RCLICK, IDC_CONTACT, &CWxBootDlg::OnNMRClickContact)
	//当点击查看联系人信息菜单
	ON_COMMAND(ID_MENU_DETAIL, &CWxBootDlg::OnContactDetailClicked)
	//当点击发送消息菜单
	ON_COMMAND(ID_MENU_SEND, &CWxBootDlg::OnSendMsg)
END_MESSAGE_MAP()


int contactCbCount = 0;

//绘制联系人列表
void drawContact(CString UserName, CString NickName, CString Remark, CString Alias)
{
	List->InsertItem(contactCbCount, UserName);
	List->SetItemText(contactCbCount, 1, NickName);
	List->SetItemText(contactCbCount, 2, Remark);
	List->SetItemText(contactCbCount, 3, Alias);
	contactCbCount++;
}

//初始化
void BotInit()
{

	//设置当前执行目录
	char szBuff[MAX_PATH] = { 0 };
	HMODULE hModuleInstance = _AtlBaseModule.GetModuleInstance();
	GetModuleFileNameA(hModuleInstance, szBuff, MAX_PATH);
	CString strTmp = CA2T(szBuff);
	CurrentExePath = strTmp.Mid(0, strTmp.ReverseFind('\\'));
	CurrentExePath += "\\";

	//socket初始化
	//SocketStart();

	//注入DLL
	InjectDLL(CurrentExePath);

	//联系人列表
	//ContactInit(0, List);
	contactCbCount = 0;
}

// CWxBootDlg 消息处理程序

BOOL CWxBootDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	//设置定时器,定时定时解密数据库,10分钟执行一次
	//SetTimer(TIMER_ID, TIMER_STEP, NULL);

	//设置默认选项
	CCombo.SetCurSel(0);
	//初始化CCombobox
	CCombo.AddString(TEXT("全部"));
	CCombo.InsertString(1, L"亲密");
	CCombo.InsertString(2, L"聊天室");
	CCombo.InsertString(3, L"朋友");
	CCombo.InsertString(4, L"陌生人");
	//设置默认选项
	CCombo.SetCurSel(0);


	//初始化列表
	List = (CListCtrl*)GetDlgItem(IDC_CONTACT);
	//初始化报表
	List->DeleteColumn(0);
	List->DeleteColumn(0);
	List->DeleteColumn(0);
	List->DeleteColumn(0);
	List->DeleteAllItems(); // 全部清空
	//设置表头 参数1:索引 2:内容 3:对齐方式 4:列宽
	List->InsertColumn(0, L"用户名", LVCFMT_LEFT, 220);
	List->InsertColumn(1, L"昵称", LVCFMT_LEFT, 240);
	List->InsertColumn(2, L"备注", LVCFMT_LEFT, 180);
	List->InsertColumn(3, L"微信ID", LVCFMT_LEFT, 180);
	//设置属性  |整行选中|显示网格
	List->SetExtendedStyle(List->GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

	BotInit();

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CWxBootDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
//HCURSOR CWxBootDlg::OnQueryDragIcon()
//{
//	return static_cast<HCURSOR>(m_hIcon);
//}


void CWxBootDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO: 在此处添加消息处理程序代码

	//发送退出消息，提醒注入器unhook


	//关闭定时器
	KillTimer(TIMER_ID);
	//卸载DLL
	UnloadDll();

}

//解密数据库方法
UINT StartDecryptDb(LPVOID lpParam)
{

	int count = 0;
	fstream in;
	fstream out;
	intptr_t handle;
	_finddata_t findData;

	CString CurrentExePath;
	//设置当前执行目录
	char szBuff[MAX_PATH] = { 0 };
	HMODULE hModuleInstance = _AtlBaseModule.GetModuleInstance();
	GetModuleFileNameA(hModuleInstance, szBuff, MAX_PATH);
	CString strTmp = CA2T(szBuff);
	CurrentExePath = strTmp.Mid(0, strTmp.ReverseFind('\\'));
	CurrentExePath += "\\";

	string path;
	string password;

	CString ini = CurrentExePath + "conf.ini";
	fstream cin;
	cin.open(ini, ios::in);
	getline(cin, path);
	getline(cin, password);
	cin.close();

	//WxDbInfo* DbInfo = (WxDbInfo*)lpParam;

	string director(path.c_str());
	director += "\\*.db";

	handle = _findfirst(director.c_str(), &findData);    // 查找目录中的第一个文件
	if (handle == -1)
	{
		DefMsg(L"Failed to find first file!");
		DefMsg((CString)director.c_str());
		return 0;
	}
	do
	{
		// 是否是子目录并且不为"."或".."
		if (!(
			findData.attrib & _A_SUBDIR
			&& strcmp(findData.name, ".") == 0
			&& strcmp(findData.name, "..") == 0
			))
		{

			long size;
			char* buffer;

			Decryptdb(director.substr(0, director.length() - 4), findData.name, password);

		}
	} while (_findnext(handle, &findData) == 0);    // 查找目录中的下一个文件

	_findclose(handle);    // 关闭搜索句柄
	return 1;
}

void CWxBootDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//开新线程解密数据库
	//AfxBeginThread(StartDecryptDb, NULL, 0, 0, NULL);

	CDialogEx::OnTimer(nIDEvent);
}

BOOL CWxBootDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//取出消息
	if (pCopyDataStruct->dwData == MSG_TAG_DB)
	{
		//微信数据库信息结构
		struct WxDbInfo
		{
			wchar_t path[0xff];			//路径
			char password[64];			//密码
		};

		//微信数据库信息实体
		WxDbInfo* WechatDbInfo = new WxDbInfo;

		WechatDbInfo = (WxDbInfo*)pCopyDataStruct->lpData;
		string path((CStringA)WechatDbInfo->path);
		CString ini = CurrentExePath + "conf.ini";
		fstream out;
		out.open(ini, ios::out);
		out << path << endl;
		out << WechatDbInfo->password << endl;
		out.close();

		//执行一次解密数据库
		//StartDecryptDb(NULL);
	}
	else if (pCopyDataStruct->dwData == MT_CONTACT_LIST) {
		UserInfo* UserDetail = new UserInfo;
		UserDetail = (UserInfo*)pCopyDataStruct->lpData;
		drawContact(UserDetail->UserNumber, UserDetail->UserNickName, UserDetail->UserRemark, UserDetail->UserId);
	}

	return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}

//选择联系人类别
void CWxBootDlg::OnCbnSelchangeComboType()
{
	// TODO: 在此添加控件通知处理程序代码
	int sel = CCombo.GetCurSel();
	ContactInit(sel, List);
	contactCbCount = 0;
}

//右键菜单
void CWxBootDlg::OnNMRClickContact(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	//*pResult = 0;

	CMenu menu;
	POINT pt = { 0 };
	GetCursorPos(&pt);//得到鼠标点击位置
	menu.LoadMenu(IDR_CONTACT_MENU);//菜单资源ID
	menu.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, this);
	DestroyMenu(menu);
}

//发送消息
void CWxBootDlg::OnSendMsg() {
	CMsg Dlg;
	Dlg.DoModal();
}

//联系人信息
void CWxBootDlg::OnContactDetailClicked()
{
	// TODO: 在此添加命令处理程序代码

	int mark = List->GetSelectionMark();
	CString UserName = List->GetItemText(mark, 0);

	MessageStruct* msg = new MessageStruct;
	wmemcpy(msg->wxid, UserName, 40);

	COPYDATASTRUCT senddata;
	senddata.dwData = MT_CONTACT_LIST;
	senddata.cbData = sizeof(MessageStruct);
	senddata.lpData = msg;

	MessageSender(senddata);

	CContactDetail Dlg;
	Dlg.DoModal();
}
